package roslan.musicbox.server.data;

import java.io.File;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Scanner;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

public class MusicTagList {
	private HashMap<String, ArrayList<ServerMusicTag> > invertedList;
	private Document xmlDoc;
	
	public int getSize(){
		return invertedList.size();
	}
	
	public MusicTagList(String filename){
		invertedList = new HashMap<String, ArrayList<ServerMusicTag> >();
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		try{
			DocumentBuilder db = dbf.newDocumentBuilder();
			xmlDoc = db.parse(new File(filename));
			NodeList nodeList = xmlDoc.getDocumentElement().getElementsByTagName("MusicTag");
			for(int i=0;i<nodeList.getLength();++i){
				Element e = (Element)nodeList.item(i);
				ServerMusicTag tag = ServerMusicTag.getTagFromElement(e);
				String title = tag.getTitle();
				if(invertedList.containsKey(title)){
					invertedList.get(title).add(tag);
				}else{
					ArrayList<ServerMusicTag> list = new ArrayList<ServerMusicTag>();
					list.clear();
					list.add(tag);
					invertedList.put(title, list);
				}
			}
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	
	public MusicTagList(){
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		try{
			DocumentBuilder db = dbf.newDocumentBuilder();
			xmlDoc = db.newDocument();
		}catch(Exception e){
			e.printStackTrace();
		}
		Element root = xmlDoc.createElement("MusicTagDatabase");
		xmlDoc.appendChild(root);
		invertedList = new HashMap<String, ArrayList<ServerMusicTag> >();
		invertedList.clear();
	}
	
	public void clear(){
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		try{
			DocumentBuilder db = dbf.newDocumentBuilder();
			xmlDoc = db.newDocument();
		}catch(Exception e){
			e.printStackTrace();
		}
		Element root = xmlDoc.createElement("MusicTagDatabase");
		xmlDoc.appendChild(root);
		invertedList.clear();
	}
	
	public void insert(ServerMusicTag tag){
		try{
			Element root = (Element)xmlDoc.getFirstChild();
			root.appendChild(tag.getElement(xmlDoc));
			String title = tag.getTitle();
			if(invertedList.containsKey(title)){
				invertedList.get(title).add(tag);
			}else{
				ArrayList<ServerMusicTag> list = new ArrayList<ServerMusicTag>();
				list.clear();
				list.add(tag);
				invertedList.put(title, list);
			}
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	
	public ArrayList<ServerMusicTag> search(String title){
		if(invertedList.containsKey(title)){
			ArrayList<ServerMusicTag> list = invertedList.get(title);
			ArrayList<ServerMusicTag> newList = new ArrayList<ServerMusicTag>();
			for(ServerMusicTag tag:list){
				newList.add(tag.clone());
			}
			return newList;
		}else{
			return new ArrayList<ServerMusicTag>(); 
		}
	}
	
	public void saveToXmlFile(String filename){
		try{
			Transformer t = TransformerFactory.newInstance().newTransformer();
			t.setOutputProperty("indent", "yes");
			t.transform(new DOMSource(xmlDoc), new StreamResult(new File(filename)));
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	
	public void cleanXmlFile(String filename){
		Scanner scanner = null;
		StringBuffer buffer = new StringBuffer();
		try{
			scanner = new Scanner(new File(filename), "utf8");
		}catch(Exception e){}
		while(scanner.hasNext()){
			String line = scanner.nextLine();
			buffer.append(line+"\r\n");
		}
		scanner.close();
	
		String content = buffer.toString();
		String regex = "\\&\\#[0-9]*";
		content = content.replaceAll(regex, "");
		PrintWriter writer = null;
		try{
			writer = new PrintWriter(filename, "utf8");
		}catch(Exception e){
		}
		writer.write(content);
		writer.flush();
		writer.close();
	}
}
